package com.wanxi.education.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wanxi.education.common.OrderStateCode;
import com.wanxi.education.controller.pay.WeiXinPayController;
import com.wanxi.education.mapper.OrderFrontMapper;
import com.wanxi.education.model.pojo.Order;
import com.wanxi.education.model.vo.order.*;
import com.wanxi.education.scheduler.OrderCheckScheduler;
import com.wanxi.education.service.OrderFrontService;
import com.wanxi.education.util.GenerateOrderNoUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: 寇文宝
 * @Description: 前端订单功能业务逻辑层
 * @Date: Created in 2021/9/24
 * @Version: 1.0
 */
@Service("orderFrontService")
public class OrderFrontServiceImpl implements OrderFrontService {
    @Autowired
    private OrderFrontMapper orderFrontMapper;

    @Autowired
    private WeiXinPayController weiXinPayController;

    /**
     * 生成订单
     *
     * @param orderAddVo 课程id，课程名称，用户id
     * @return 返回确认订单页面所需数据
     */
    @Transactional
    @Override
    public OrderFindByIdVo generateOrder(OrderAddVo orderAddVo) {
        // 1.通过课程id去查询课程价格
        BigDecimal price = orderFrontMapper.findPrice(orderAddVo.getCourseId());
        // 2.通过课程id查找课程名字
        String courseName = orderFrontMapper.findCourseName(orderAddVo.getCourseId());
        // 3.通过用户id查询所属机构id
        Long agencyId = orderFrontMapper.findAgencyId(orderAddVo.getUserId());
        // 4.设置订单参数
        Order order = new Order();
        order.setPrice(price);
        order.setAgencyId(agencyId);
        order.setUserId(orderAddVo.getUserId());
        order.setCourseId(orderAddVo.getCourseId());
        order.setCourseName(courseName);
        // 5.订单状态为未支付--2
        order.setOrderState(OrderStateCode.UNPAID.getCode());
        // 6.支付方式为暂未进行支付 2表示暂未进行支付
        order.setPaymentMethod(2);
        // 7.生成订单号
        order.setOrderNumber(GenerateOrderNoUtil.getOrderNo());
        // 8.生成订单
        orderFrontMapper.generateOrder(order);
        // 9.订单生成成功后设置30分钟超时未支付自动取消订单
        // 创建延时队列
        DelayQueue queue = new DelayQueue<>();
        OrderDelayVo orderDelayVo = new OrderDelayVo();
        orderDelayVo.setId(order.getId());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, 30);//过期时间30分钟
        orderDelayVo.setExpirationTime(calendar.getTime());
        //运行线程
        ExecutorService exec = Executors.newFixedThreadPool(1);
        exec.execute(new OrderCheckScheduler(queue));
        //往队列中放入数据
        queue.offer(orderDelayVo);
        exec.shutdown();
        // 10.生成订单完成后返回给前端的信息
//        //    查询证书名称
//        String certificateName = orderFrontMapper.findCertificateName(order.getId());
//        //    查询机构名称
//        String agencyName = orderFrontMapper.findAgencyName(order.getId());
//        //    查询课程时长
//        Integer studyLength = orderFrontMapper.findStudyLengthByCourseId(orderAddVo.getCourseId());
//        // 11.封装前端需要的信息
//        OrderAddBackVo orderAddBackVo = new OrderAddBackVo();
//        orderAddBackVo.setId(order.getId());
//        orderAddBackVo.setStudyLength(studyLength);
//        orderAddBackVo.setOrderNumber(order.getOrderNumber());
//        orderAddBackVo.setCertificateName(certificateName);
//        orderAddBackVo.setAgencyName(agencyName);
//        orderAddBackVo.setCourseName(courseName);
//        orderAddBackVo.setPrice(order.getPrice());
//        orderAddBackVo.setCreateTime(new Date());
        OrderFindByIdVo orderFindByIdVo = findById(order.getId(), order.getUserId());
        return orderFindByIdVo;
    }

    /**
     * 前端用户个人中心订单查询
     *
     * @param pageNum  当前页
     * @param pageSize 每页显示多少条
     * @return 返回分页查询数据
     */
    @Override
    public PageInfo<OrderGoFrontVo> findPage(Integer pageNum, Integer pageSize, Long userId) {
        PageHelper.startPage(pageNum, pageSize);
        List<OrderGoFrontVo> orderGoFrontVoList = orderFrontMapper.findPage(userId);
        return new PageInfo<>(orderGoFrontVoList);
    }

    /**
     * 前端用户查看订单详情
     *
     * @param id     订单id
     * @param userId 用户id
     * @return 返回订单详情页面所需数据
     */
    @Transactional
    @Override
    public OrderFindByIdVo findById(Long id, Long userId) {
        OrderFindByIdVo orderFindByIdVo = orderFrontMapper.findById(id, userId);
        String certificateName = orderFrontMapper.findCertificateName(id);
        orderFindByIdVo.setCertificateName(certificateName);
        return orderFindByIdVo;
    }

    /**
     * 用户取消订单
     *
     * @param id     订单id
     * @param userId 用户id
     * @return 返回操作后的状态
     */
    @Transactional
    @Override
    public int cancel(Long id, Long userId) {
        OrderFindByIdVo byId = orderFrontMapper.findById(id, userId);
        if (byId.getOrderState() != null && byId.getOrderState().equals(OrderStateCode.UNPAID.getCode())) {
            orderFrontMapper.cancel(id, userId);
            return 1;
        }
        return 0;
    }

    /**
     * 支付成功
     * 绑定用户和证书
     * 添加售卖量
     *
     * @param outTradeNo    订单号
     * @param transactionId 微信支付流水号
     */
    @Override
    @Transactional
    public void payMoney(String outTradeNo, String transactionId) {
        //判断订单是否存在
        Integer num = orderFrontMapper.findOrder(outTradeNo);
        if (num.equals(1)) {
            //修改订单状态为支付成功
            orderFrontMapper.payMoney(outTradeNo, transactionId);
            //查找订单所属用户id和证书id
            CcieIdAndUserIdVo ccieIdAndUserIdVo = orderFrontMapper.findCcieIdAndUserId(outTradeNo);
            //将用户和证书绑定
            orderFrontMapper.bindCcieAndUser(ccieIdAndUserIdVo.getUserId(), ccieIdAndUserIdVo.getCcieId());
            //将课程售卖量加一
            Integer sale = 1;
            orderFrontMapper.updateCourseSale(outTradeNo, sale);
        }
    }

    /**
     * 查询订单状态是否为支付成功
     *
     * @param orderNumber 订单号
     * @param userId      用户id
     * @param status      查询方式
     * @return
     */
    @Override
    public Integer searchOrderState(String orderNumber, Long userId ,Integer status) {
        // 如果status = 1 主动询问微信端是否支付成功
        if (status.equals(1)) {
            // 主动向微信端发起查询订单支付状态
            weiXinPayController.queryOrder(orderNumber);
        }
        // 查询数据库
        Integer integer = orderFrontMapper.searchOrderState(orderNumber, userId);
        // 查询失败，订单号不存在，或订单和用户id不匹配
        if (ObjectUtils.isEmpty(integer)) {
            // 返回null
            return integer;
        }
        return integer;
    }

    /**
     * 超时未支付自动取消订单
     *
     * @param id 订单id
     */
    @Override
    @Transactional
    public void autoCancelOrder(Long id) {
        Integer orderState = orderFrontMapper.findOrderState(id);
        if (orderState.equals(OrderStateCode.UNPAID.getCode())) {
            orderFrontMapper.autoCancelOrder(id);
        }
    }

    /**
     * 订单支付失败
     *
     * @param outTradeNo 订单号
     */
    @Override
    public void payFailed(String outTradeNo) {
        orderFrontMapper.payFailed(outTradeNo);
    }
}
